bitkeeper revision 1.1026.2.1 (40e1764d1ndRTs9hmUyiBLEHi5_V3A)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Jun 2004 14:01:49 +0000 (14:01 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Jun 2004 14:01:49 +0000 (14:01 +0000)
Fix network backend bugs. It isn't safe to use skb->cb[] for our own
purposes after all. :-(

linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c
linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c

index 67de9983046871af4c96e59adc353d61081efa3f..8bdfdbdb1f6a9550de4477dcf62f094933976286 100644 (file)
@@ -28,12 +28,6 @@ static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
 static void net_rx_action(unsigned long unused);
 static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0);
 
-typedef struct {
-    u16 id;
-    unsigned long old_mach_ptr;
-    unsigned long new_mach_pfn;
-    netif_t *netif;
-} rx_info_t;
 static struct sk_buff_head rx_queue;
 static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2];
 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE*3];
@@ -48,8 +42,10 @@ static unsigned long mmap_vstart;
 
 #define PKT_PROT_LEN (ETH_HLEN + 20)
 
-static u16 pending_id[MAX_PENDING_REQS];
-static netif_t *pending_netif[MAX_PENDING_REQS];
+static struct {
+    netif_tx_request_t req;
+    netif_t *netif;
+} pending_tx_info[MAX_PENDING_REQS];
 static u16 pending_ring[MAX_PENDING_REQS];
 typedef unsigned int PEND_RING_IDX;
 #define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
@@ -61,11 +57,6 @@ static u16 dealloc_ring[MAX_PENDING_REQS];
 static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED;
 static PEND_RING_IDX dealloc_prod, dealloc_cons;
 
-typedef struct {
-    u16 idx;
-    netif_tx_request_t req;
-    netif_t *netif;
-} tx_info_t;
 static struct sk_buff_head tx_queue;
 static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
 
@@ -127,6 +118,8 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     netif_t *netif = (netif_t *)dev->priv;
 
+    ASSERT(skb->dev == dev);
+
     /* Drop the packet if the target domain has no receive buffers. */
     if ( (netif->rx_req_cons == netif->rx->req_prod) ||
          ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
@@ -152,15 +145,14 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
         skb_reserve(nskb, hlen);
         __skb_put(nskb, skb->len);
         (void)skb_copy_bits(skb, -hlen, nskb->head, hlen + skb->len);
+        nskb->dev = skb->dev;
         dev_kfree_skb(skb);
         skb = nskb;
     }
 
-    ((rx_info_t *)&skb->cb[0])->id    =
-        netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_req_cons++)].req.id;
-    ((rx_info_t *)&skb->cb[0])->netif = netif;
-        
-    __skb_queue_tail(&rx_queue, skb);
+    netif->rx_req_cons++;
+
+    skb_queue_tail(&rx_queue, skb);
     tasklet_schedule(&net_rx_tasklet);
 
     return 0;
@@ -195,7 +187,7 @@ static void net_rx_action(unsigned long unused)
     netif_t *netif;
     s8 status;
     u16 size, id, evtchn;
-    mmu_update_t *mmu = rx_mmu;
+    mmu_update_t *mmu;
     multicall_entry_t *mcl;
     unsigned long vdata, mdata, new_mfn;
     struct sk_buff_head rxq;
@@ -206,9 +198,10 @@ static void net_rx_action(unsigned long unused)
     skb_queue_head_init(&rxq);
 
     mcl = rx_mcl;
-    while ( (skb = __skb_dequeue(&rx_queue)) != NULL )
+    mmu = rx_mmu;
+    while ( (skb = skb_dequeue(&rx_queue)) != NULL )
     {
-        netif   = ((rx_info_t *)&skb->cb[0])->netif;
+        netif   = (netif_t *)skb->dev->priv;
         vdata   = (unsigned long)skb->data;
         mdata   = virt_to_machine(vdata);
         new_mfn = get_new_mfn();
@@ -231,11 +224,9 @@ static void net_rx_action(unsigned long unused)
         mcl[1].args[1] = 3;
         mcl[1].args[2] = 0;
 
-        mmu += 3;
         mcl += 2;
+        mmu += 3;
 
-        ((rx_info_t *)&skb->cb[0])->old_mach_ptr = mdata;
-        ((rx_info_t *)&skb->cb[0])->new_mach_pfn = new_mfn;
         __skb_queue_tail(&rxq, skb);
 
         /* Filled the batch queue? */
@@ -250,14 +241,17 @@ static void net_rx_action(unsigned long unused)
     (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
 
     mcl = rx_mcl;
+    mmu = rx_mmu;
     while ( (skb = __skb_dequeue(&rxq)) != NULL )
     {
-        netif   = ((rx_info_t *)&skb->cb[0])->netif;
+        netif   = (netif_t *)skb->dev->priv;
         size    = skb->tail - skb->data;
-        id      = ((rx_info_t *)&skb->cb[0])->id;
-        new_mfn = ((rx_info_t *)&skb->cb[0])->new_mach_pfn;
-        mdata   = ((rx_info_t *)&skb->cb[0])->old_mach_ptr;
 
+        /* Rederive the machine addresses. */
+        new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
+        mdata   = ((mmu[2].ptr & PAGE_MASK) |
+                   ((unsigned long)skb->data & ~PAGE_MASK));
+        
         /* Check the reassignment error code. */
         if ( unlikely(mcl[1].args[5] != 0) )
         {
@@ -285,6 +279,7 @@ static void net_rx_action(unsigned long unused)
         }
 
         evtchn = netif->evtchn;
+        id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
         if ( make_rx_response(netif, id, status, mdata, size) &&
              (rx_notify[evtchn] == 0) )
         {
@@ -295,6 +290,7 @@ static void net_rx_action(unsigned long unused)
         dev_kfree_skb(skb);
 
         mcl += 2;
+        mmu += 3;
     }
 
     while ( notify_nr != 0 )
@@ -406,10 +402,11 @@ static void net_tx_action(unsigned long unused)
     {
         pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
 
-        netif = pending_netif[pending_idx];
+        netif = pending_tx_info[pending_idx].netif;
 
         spin_lock(&netif->tx_lock);
-        make_tx_response(netif, pending_id[pending_idx], NETIF_RSP_OKAY);
+        make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
+                         NETIF_RSP_OKAY);
         spin_unlock(&netif->tx_lock);
         
         pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
@@ -512,10 +509,11 @@ static void net_tx_action(unsigned long unused)
         mcl[0].args[2] = 0;
         mcl[0].args[3] = netif->domid;
         mcl++;
-        
-        ((tx_info_t *)&skb->cb[0])->idx = pending_idx;
-        ((tx_info_t *)&skb->cb[0])->netif = netif;
-        memcpy(&((tx_info_t *)&skb->cb[0])->req, &txreq, sizeof(txreq));
+
+        memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
+        pending_tx_info[pending_idx].netif = netif;
+        *((u16 *)skb->data) = pending_idx;
+
         __skb_queue_tail(&tx_queue, skb);
 
         pending_cons++;
@@ -533,9 +531,9 @@ static void net_tx_action(unsigned long unused)
     mcl = tx_mcl;
     while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
     {
-        pending_idx = ((tx_info_t *)&skb->cb[0])->idx;
-        netif       = ((tx_info_t *)&skb->cb[0])->netif;
-        memcpy(&txreq, &((tx_info_t *)&skb->cb[0])->req, sizeof(txreq));
+        pending_idx = *((u16 *)skb->data);
+        netif       = pending_tx_info[pending_idx].netif;
+        memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
 
         /* Check the remap error code. */
         if ( unlikely(mcl[0].args[5] != 0) )
@@ -581,8 +579,6 @@ static void net_tx_action(unsigned long unused)
          */
         page->mapping = (struct address_space *)netif_page_release;
         atomic_set(&page->count, 1);
-        pending_id[pending_idx] = txreq.id;
-        pending_netif[pending_idx] = netif;
 
         netif->stats.tx_bytes += txreq.size;
         netif->stats.tx_packets++;
index 25bad4b5767b003d53290260fdcd1c92c0e0326c..9074ad6ded55c18ed8de415215792ba411528253 100644 (file)
@@ -99,8 +99,6 @@ static struct net_device *find_dev_by_handle(unsigned int handle)
     return NULL;
 }
 
-#define MULTIVIF
-
 /** Network interface info. */
 struct netif_ctrl {
     /** Number of interfaces. */
@@ -385,14 +383,8 @@ static void netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
     unsigned long flags;
 
     spin_lock_irqsave(&np->tx_lock, flags);
-    
-    if( !netif_carrier_ok(dev) )
-    {
-        spin_unlock_irqrestore(&np->tx_lock, flags);
-        return;
-    }
-    
-    network_tx_buf_gc(dev);
+    if ( likely(netif_carrier_ok(dev)) )
+        network_tx_buf_gc(dev);
     spin_unlock_irqrestore(&np->tx_lock, flags);
 
     if ( np->rx_resp_cons != np->rx->resp_prod )
@@ -414,7 +406,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
 
     spin_lock(&np->rx_lock);
 
-    /* if the device is undergoing recovery then don't do anything */
+    /* If the device is undergoing recovery then don't do anything. */
     if ( !netif_carrier_ok(dev) )
     {
         spin_unlock(&np->rx_lock);
@@ -721,20 +713,17 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
 
         memcpy(dev->dev_addr, status->mac, ETH_ALEN);
 
-        if(netif_carrier_ok(dev)){
+        if ( netif_carrier_ok(dev) )
             np->state = NETIF_STATE_CONNECTED;
-        } else {
+        else
             network_reconnect(dev, status);
-        }
 
         np->evtchn = status->evtchn;
         np->irq = bind_evtchn_to_irq(np->evtchn);
         (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 
                           dev->name, dev);
         
-#ifdef MULTIVIF
         netctrl_connected_count();
-#endif
         break;
 
     default:
@@ -744,13 +733,13 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
     }
 }
 
-/** Create a network devices.
- *
+/** Create a network device.
  * @param handle device handle
  * @param val return parameter for created device
  * @return 0 on success, error code otherwise
  */
-static int create_netdev(int handle, struct net_device **val){
+static int create_netdev(int handle, struct net_device **val)
+{
     int err = 0;
     struct net_device *dev = NULL;
     struct net_private *np = NULL;
@@ -847,11 +836,7 @@ static int __init init_module(void)
 {
     ctrl_msg_t                       cmsg;
     netif_fe_driver_status_changed_t st;
-    int err = 0;
-#ifdef MULTIVIF
-    int wait_n = 20;
-    int wait_i;
-#endif
+    int err = 0, wait_i, wait_n = 20;
 
     if ( (start_info.flags & SIF_INITDOMAIN) ||
          (start_info.flags & SIF_NET_BE_DOMAIN) )
@@ -860,9 +845,8 @@ static int __init init_module(void)
     printk("Initialising Xen virtual ethernet frontend driver");
 
     INIT_LIST_HEAD(&dev_list);
-#ifdef MULTIVIF
+
     netctrl_init();
-#endif
 
     (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
                                     CALLBACK_IN_BLOCKING_CONTEXT);
@@ -876,7 +860,6 @@ static int __init init_module(void)
     memcpy(cmsg.msg, &st, sizeof(st));
     ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
 
-#ifdef MULTIVIF
     /* Wait for all interfaces to be connected. */
     for ( wait_i = 0; ; wait_i++)
     {
@@ -888,7 +871,6 @@ static int __init init_module(void)
         set_current_state(TASK_INTERRUPTIBLE);
         schedule_timeout(1);
      }
-#endif
 
     if ( err )
         ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);